<?
/**
 * Core class (Engine accounts & modules).
 *
 * This is the general overview file - all accounts and modules.
 *
 * Please read the LICENSE file
 * @license 	GNU Lesser General Public License
 * @copyright 	oneDot only <we@onedotonly.be>
 * @author 		Koen Betsens <koen@onedotonly.be>
 *
 * @package 	Core
 *
 * @todo		Rename deprecated "Core" trough-out the engine to this use
 */
 
 /**
 * Core class
 *
 * Currently named OVERVIEW, since CORE already exists...
 *
 * @package 	Core
 *
 * @todo		Rename deprecated "Core" trough-out the engine to this use, then rename "OVERVIEW"
 */
class OVERVIEW {
	
	/**
	 * accountname column / meta value
	 * @name account_column string
	 */
    const account_column = "root";
    
    /**
	 * module filetypes
	 * @var	array
	 */
    var $module_filetypes = array( "construct.inc", "module.php", "script.js", "style.css" );
    
    /**
	 * accounts list
	 * @var array
	 */
    var $accountlist;
    
    /**
	 * modules list
	 * @var array
	 */
    var $modulelist;
    
    /**
	 * Constructs the Core object
	 *
	 * @return	object
	 */
	function __construct() {
		global $CDB;
		
		if( $CDB ) $this->DB = $CDB;
		else exit( "core database not found" );

#		Accounts
		$this->listAccounts();
				
#		Mods
		$this->listModules();
	}

	/**
	 * Output Accounts
	 *
	 * Return the (stored) accounts, as array or json object string
	 *
	 * @param 	mixed 	$json		If set, json object string is returned (defaults false)
	 * @return	array|json	all accounts in array	
	 */
	public function accounts( $json = false ) {
		
		return $json? json_encode( $this->accountlist ): $this->accountlist;
	}
	
	/**
	 * Output Modules
	 *
	 * Return the (stored) modules, as array or json object string
	 *
	 * @param 	mixed 	$json		If set, json object string is returned (defaults false)
	 * @return	array|json	all modules in array	
	 */
	public function modules( $json = false ) {
		
		return $json? json_encode( $this->modulelist ): $this->modulelist;
	}
	
	
	/**
	 * List Accounts
	 *
	 * Retreive all accounts
	 */
	private function listAccounts() {
		
		if( $projects = $this->DB->filter_objects( "project", "ID>0" ))
			
			foreach( $projects as $Obj )
				$this->accountlist[] = ( $Obj->active())? $this->renderActiveAccount( $Obj ) : $this->renderPassiveAccount( $Obj );		
	}
	
	/**
	 * List global Modules
	 *
	 * Retreive all the global mods, with their containing files (as type integers)
	 *
	 * @return	array	all global mods	
	 */
	private function listModules() {
		
		if( $modules = scandir( $root = ENGINE_CORE . "modules" ))
			foreach( $modules as $dir )
				if ( strpos( $dir, "." ) !== 0 && is_dir( "$root/$dir" ))
				 
					if( $files = scandir( "$root/$dir" ))
						foreach( $files as $file )
							if ( strpos( $file, "." ) !== 0 && $fileid = array_search( $file , $this->module_filetypes ))
								 $this->modulelist[ $dir ][ "files" ][] = $fileid;

	}
	
	/**
	 * Create account-level Database Class
	 *
	 * Return the account-level DB object, based on account root
	 *
	 * @param 	string	$root	Account root directory
	 * @return	object	DB database object (account-level)	
	 */
	private function connectDB( $root ) {
		
		include ( ROOT . "/$root/custom.root/.inflame" );

		return new DB( $dbhost, $dbuser, $dbpass, $dbname );
	}

	/**
	 * Retreive account data (active)
	 *
	 * Returns the data from the given account object as array. An active account is a engine-based account
	 *
	 * @param 	object 	$Account	the account OBJECT object.
	 * @return	array	the account data	
	 */
	private function renderActiveAccount( $Account ) {
	
		$DB = $Account->db = $this->connectDB( $Account->get( self::account_column ));
		
		$list = array(
			"id"		=> $Account->id,
			"dbname"	=> $DB->dbname,
			"users"		=> $DB->count( 'user', "ID>0" ),
			"pages"		=> $DB->count( 'page', "ID>0" ),
			"mods"		=> $modcount = (int) $DB->query_direct( "select count(*) -2 from moddump" ),
			"pagesidle"	=> $DB->count( "page", "!active" ),
			"modlist"	=> $this->calculateAccountMods( $Account ),
			"modslocal"	=> $this->calculateLocalMods( $Account->get( self::account_column ))
		);

		return array_merge( $list, $this->renderPassiveAccount( $Account ));
	}
	
	/**
	 * Retreive account data (passive)
	 *
	 * Returns the data from the given account object as array. A passive account is non engine based (or on deprecated engine version)
	 *
	 * @param 	object 	$Account	the account OBJECT object.
	 * @return	array	the account data	
	 */
	private function renderPassiveAccount( $Account ) {
		
		$list = array(
			"name"		=> $Account->get( "name" ),
			"root"		=> $Account->get( self::account_column ),
			"size"		=> ( $gb = $Account->get( "dirsize" ))? "$gb gb": "load"
		);
		
		return $list;
	}

	
	/**
	 * Return Account mods
	 *
	 * Returns the mods actually used in the given account (mixed local/global)
	 *
	 * @param 	object 	$Account	the account OBJECT object.
	 * @return	array	the account-level used mods	
	 */
	private function calculateAccountMods( $Account ) {
		global $DB;
		
		
		
		$DB = $Account->db;
		
		if( $pages = $DB->filter_objects( "page", "length(mods) > 3" ))
			foreach( $pages as $Page )
			
				foreach( json_decode( $Page->get( "mods" )) as $mod )
					
					if( is_array( $mod )) foreach( $mod as $n ) {
						
						$module = json_decode( $DB->query_direct( "select json from moddump where ID='$n'" ));
						$mods[ $module->mod ][ $module->action ][] = $Page->id;
					}		

		return $mods;
		
	}
	
	/**
	 * Return local Account mods
	 *
	 * Returns the mods locally stored
	 *
	 * @param 	object 	$Account	the account OBJECT object.
	 * @return	array	the account-level used mods	
	 */
	private function calculateLocalMods( $root ) {
		global $DB;
		
		if( is_dir( $root = ROOT . "/$root/custom.root/modules" ) && ( $modules = scandir( $root )))
			foreach( $modules as $dir )
				if ( strpos( $dir, "." ) !== 0 )
				 
					if( $files = scandir( "$root/$dir" ))
						foreach( $files as $file )
							if ( strpos( $file, "." ) !== 0 && $fileid = array_search( $file , $this->module_filetypes ))
								 $mods[ $dir ][] = $fileid;

		return $mods;
		
	}

}